package org.cqc.utils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;

/**
 * @author yang.zz
 * @date 2020/7/30 10:34
 */
@Slf4j
public class JsonUtil {

    private static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

    private JsonUtil() {
    }

    public static Gson getInstance() {
        return SingletonHolder.INSTANCE;
    }

    /**
     * 对象转成json
     *
     * @param object
     * @return json
     */
    public static String objectToJson(Object object) {
        return getInstance().toJson(object);
    }

    public static Map<String, Object> objectToMap(Object obj) {
        if (obj == null) {
            return new HashMap<>();
        }
        try {
            Map<String, Object> map = new HashMap<String, Object>();
            Field[] classFields = obj.getClass().getDeclaredFields();
            for (Field field : classFields) {
                field.setAccessible(true);
                map.put(field.getName(), field.get(obj));
            }
            Field[] superclassFields = obj.getClass().getSuperclass().getDeclaredFields();

            for (Field field : superclassFields) {
                field.setAccessible(true);
                map.put(field.getName(), field.get(obj));
            }
            return map;
        } catch (Exception e) {
            log.info("对象转换map异常:{}", e);
            return new HashMap<>();
        }
    }

    /**
     * Json转成对象
     *
     * @param jsonString
     * @param cls
     * @return 对象
     */
    public static <T> T jsonToBean(String jsonString, Class<T> cls) {
        return getInstance().fromJson(jsonString, cls);
    }

    /**
     * Json转成对象
     *
     * @param jsonString
     * @param typeOfT
     * @return T
     * @author caoqc
     * @date 2022-01-27 16:11
     */
    public static <T> T jsonToBean(String jsonString, Type typeOfT) {
        return getInstance().fromJson(jsonString, typeOfT);
    }

    /**
     * json转成list<T>
     *
     * @param jsonString
     * @param cls
     * @return list<T>
     */
    public static <T> List<T> jsonToList(String jsonString, Class<T> cls) {
        return getInstance().fromJson(jsonString, new TypeToken<List<T>>() {
        }.getType());
    }

    public static <T> List<T> jsonToListV2(String jsonString, Class<T> cls) {
        T[] t = getInstance().fromJson(jsonString, TypeToken.getArray(cls).getType());
        return t == null ? null : Arrays.asList(t);
    }

    public static <T> List<T> jsonToList(String jsonString, Type type) {
        return getInstance().fromJson(jsonString, type);
    }

    /**
     * json转成list中有map的
     *
     * @param jsonString
     * @return List<Map < String, T>>
     */
    public static <T> List<Map<String, T>> jsonToListMap(String jsonString) {

        return getInstance().fromJson(jsonString, new TypeToken<List<Map<String, T>>>() {
        }.getType());
    }

    /**
     * json转成map的
     *
     * @param jsonString
     * @return Map<String, T>
     */
    public static <T> Map<String, T> jsonToMap(String jsonString) {

        return getInstance().fromJson(jsonString, new TypeToken<Map<String, T>>() {
        }.getType());
    }

    /**
     * json转成map的
     *
     * @param jsonString
     * @return Map<String, String>
     */
    public static Map<String, String> jsonToStringMap(String jsonString) {

        return getInstance().fromJson(jsonString, new TypeToken<Map<String, String>>() {
        }.getType());
    }

    /**
     * json 转jsonArray
     *
     * @param jsonString
     * @return JsonArray
     */
    public static JsonArray jsonToJsonArray(String jsonString) {
        return new JsonParser().parse(jsonString).getAsJsonArray();
    }

    private static class SingletonHolder {
        private final static Gson INSTANCE = new GsonBuilder().serializeNulls().disableHtmlEscaping().setDateFormat(DATE_FORMAT).create();

        private SingletonHolder() {
        }
    }

}
